#include "opentreethread.h"
#include <QDir>
#include "protreeitem.h"
#include "const.h"

OpenTreeThread::OpenTreeThread(const QString &src_path, int &file_count, QTreeWidget *self, QObject *parent)
    : QThread(parent), _src_path(src_path), _file_count(file_count), _bstop(false), _self(self), _root(nullptr)
{}

// ProTreeWidget.cpp 文件中 _thread_open_pro.start() 启动之后，实际会调用的函数
void OpenTreeThread::run()
{
    if(_bstop == true) return; // 判断是否可以退出 ---> 及时退出

    if(_bstop == true){
        auto path = dynamic_cast<ProTreeItem*>(_root)->GetPath();
        auto index = _self->indexOfTopLevelItem(_root);
        delete _self->takeTopLevelItem(index);
        QDir dir(path);
        dir.removeRecursively();

        return;
    }

    // OpenTreeThread(_src_path, _file_count, _self); // 是调用下面的函数，怪不得点击了"打开项目"，并点击了对应的文件夹，却没有把文件夹给加载显示进来的哦
    OpenProTree(_src_path, _file_count, _self);
}

void OpenTreeThread::OpenProTree(const QString &src_path, int &file_count, QTreeWidget *self)
{
    QDir src_dir(src_path);
    QString name = src_dir.dirName();
    auto* item = new ProTreeItem(self, name, src_path, TreeItemPro);
    item->setData(0, Qt::DisplayRole, name);
    item->setData(0, Qt::DecorationRole, QIcon(":/icon/dir.png")); // 是一个目录 ProTreeItem 类型的哦
    item->setData(0, Qt::ToolTipRole, src_path);
    _root = item;

    // 又是一个递归调用的函数
    RecursiveProTree(src_path, file_count, self, item, item, nullptr);
}

// 递归加载图片/文件的函数（其实就是递归加载图片的函数 <--- 下面判断了文件的后缀的哦）
void OpenTreeThread::RecursiveProTree(const QString &src_path, int &file_count,
                                      QTreeWidget *self, QTreeWidgetItem *root, QTreeWidgetItem *parent, QTreeWidgetItem *preitem)
{
    QDir src_dir(src_path);
    src_dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
    src_dir.setSorting(QDir::Name);

    QFileInfoList list = src_dir.entryInfoList();
    for(int i = 0; i < list.size(); i++){
        if(_bstop == true) return;

        // 获取文件信息
        QFileInfo fileInfo = list.at(i); // 取出 QFileInfoList 中的每一个 QFileInfo
        bool bIsDir = fileInfo.isDir();
        if(bIsDir == true){
            // 是目录的情况 ---> 创建一个 ProTreeItem 作为目录，再递归下去
            if(_bstop == true) return;
            file_count++;
            emit SigUpdateProgress(file_count);

            // 因为是一个目录，所以下面的 item 是一个目录， type == TreeItemDir
            auto* item = new ProTreeItem(_root, fileInfo.fileName(), fileInfo.absoluteFilePath(), _root, TreeItemDir); // 目录
            item->setData(0, Qt::DisplayRole, fileInfo.fileName());
            item->setData(0, Qt::DecorationRole, QIcon(":/icon/dir.png"));
            item->setData(0, Qt::ToolTipRole, fileInfo.absoluteFilePath());

            RecursiveProTree(fileInfo.absoluteFilePath(), file_count, self, root, item, preitem); // 递归调用
        }else{
            // 不是目录的情况 ---> 直接创建一个 ProTreeItem 作为一个图片/文件
            if(_bstop == true) return;

            // 判断后缀是否是图片
            auto suffix = fileInfo.suffix();
            if(suffix != "png" && suffix != "jpg" && suffix != "jpeg"){
                continue;
            }
            file_count++;
            emit SigUpdateProgress(file_count);

            //
            auto* item = new ProTreeItem(_root, fileInfo.fileName(), fileInfo.absoluteFilePath(), _root, TreeItemPic); // 图片
            item->setData(0, Qt::DisplayRole, fileInfo.fileName());
            item->setData(0, Qt::DecorationRole, QIcon(":/icon/pic.png"));
            item->setData(0, Qt::ToolTipRole, fileInfo.absoluteFilePath());

            // 构造一个双向链表
            if(preitem != nullptr){
                auto* pre_proitem = dynamic_cast<ProTreeItem*>(preitem);
                pre_proitem->SetNextItem(item);
            }
            item->SetProItem(preitem);
            preitem = item; // 向后走一步：把当前节点更新成前一个节点
        }
    }

    // QFileInfoList list 都遍历完了 ---> 都加载完了
    emit SigFinishProgress(file_count);
}

// 取消信号的槽函数
void OpenTreeThread::SlotCancelOpenProgress()
{
    _bstop = true;
}
